package loan.calc.datasource;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@Aspect
@Slf4j
public class DynamicDataSourceAspect {

    @Pointcut("@annotation(UseDataSource)")
    public void dataSourcePointCut(){

    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String dsKey = getDSAnnotation(joinPoint).value();
        DynamicDataSource.setCurrent(dsKey);
        try{
            log.debug("当前数据源切换为:[" + dsKey + "]");
            return joinPoint.proceed();
        } finally {
            DynamicDataSource.clear();
            log.debug("切换为默认数据源:[" + DynamicDataSource.getCurrent() + "]");
        }
    }

    /**
     * 根据类或方法获取数据源注解
     */
    private UseDataSource getDSAnnotation(ProceedingJoinPoint joinPoint){
        Class<?> targetClass = joinPoint.getTarget().getClass();
        UseDataSource dsAnnotation = targetClass.getAnnotation(UseDataSource.class);
        // 先判断类的注解，再判断方法注解
        if(Objects.nonNull(dsAnnotation)){
            return dsAnnotation;
        }else{
            MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
            return methodSignature.getMethod().getAnnotation(UseDataSource.class);
        }
    }
}
